package com.syg.rabbitmq.consumer;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * <img width="宽度" height="高度" src="../../../../../resources/picture/RabbitMQ概览.png" alt="RabbitMQ概览">
 *     <br/>
 *
 * <img width="宽度" height="高度" src="../../../../../resources/picture/simple模式.png" alt="简单模式默认交换机">
 *     <br/>
 * 1,简单队列模式（simple模式）：<br/>
 *    不用显示声明交换机,只需要声明一个队列。生产者指定队列名发送消息给MQ，然后会有一个默认的交换机将消息发送给这个队列。
 *    消费者负责监听这个队列，一有消息就会得到通知做出相应。
 */
public class Simple_Consumer {

    public static void main(String[] args) throws IOException, TimeoutException {
        // 1,创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();

        //2,设置参数  设定连接信息，基操
        factory.setHost("127.0.0.1");
        factory.setPort(5672);  //注意这里写5672，是amqp协议端口
        factory.setUsername("guest");
        factory.setPassword("guest");
        // 为什么这里声明虚拟主机会报错呢？
        factory.setVirtualHost("/");

        // 3,创建连接
        Connection connection = factory.newConnection();
        // 4,创建Channel
        Channel channel = connection.createChannel();


        // 5,创建队列，如果此队列不存在，会自动创建
        /*
                queue:队列名称
                durable:是否持久化,当mq重启之后还在。
                exclusive：是否独占。只能有一个消费者监听这个队列。当connection关闭时,是否删除
                autoDelete：是否自动删除，当没有消费者监听时,删除
         */
        // 如果没有yyds的队列,则会创建一个队列，如果存在则不创建。
        channel.queueDeclare("yyds", false, false, false, null);
        /**
         * basicConsume方法参数如下：
         *      queue  -  消息队列名称，直接指定。
         *      autoAck - 自动应答，消费者从消息队列取出数据后，需要跟服务器进行确认应答，当服务器收到确认后，会自动将消息删除，如果开启自动应答，那么消息发出后会直接删除。
         *      callback  -  回调方法
         */
        Consumer consumer = new DefaultConsumer(channel) {
            /*
            * 回调方法，当收到消息后，会自动执行该方法
            * 1，consumerTag :标识
            * 2，Envelope 获取交换机、路由等信息
            * */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("consumerTag=" + consumerTag);
                System.out.println("Exchange=" + envelope.getExchange());
                System.out.println("RoutingKey=" + envelope.getRoutingKey());
                System.out.println("properties=" + properties);
                System.out.println("body=" + new String(body));
            }
        };
        // autoAck 为false,消费者启动时会再次消费之前的数据(可能是使用方式不对)
        channel.basicConsume("yyds", false, consumer);

    }
}
